package main

import (
  /* 标准包 */
  // "time"
  // "log"
  "fmt"
  "os"

  /* 项目内部包 */
  "dog.com"
  "dog.com/lru"
  "dog.com/http"
  "dog.com/redis"
  "dog.com/mysql"
  "dog.com/log"
  "dog.com/conf"
  "dog.com/processor"

  /* 第三方包 */
  "daemon-master"
  "github.com/op/go-logging"
  "github.com/go-ini/ini"
)

type ValueTest struct {
  name string
}

func (value *ValueTest) PointSetName (name string ) {
  value.name = name
}
func (value ValueTest) SetName (name string ) {
  value.name = name
}

func myLruTest() {

    // var test *dog.Test
    test := new (dog.Test)
    test.Name = "no beijing!"
    println("test = " , test.Name)

    //初始化lru队列
    st_lru := new(lru.Lru)
    st_lru.Init();

/*
    st_lru.Process(lru.LruData{Key:"key1", Timestamp:12345678, PageViews :0 })
    st_lru.Process(lru.LruData{Key:"key2", Timestamp:12345678, PageViews :2 })
    st_lru.Process(lru.LruData{Key:"key3", Timestamp:12345678, PageViews :4 })
    st_lru.Process(lru.LruData{Key:"key4", Timestamp:12345678, PageViews :6 })
    st_lru.Process(lru.LruData{Key:"key4", Timestamp:12345678, PageViews :8 })
    st_lru.Process(lru.LruData{Key:"key5", Timestamp:12345678, PageViews :8 })
    st_lru.Process(lru.LruData{Key:"key2", Timestamp:12345678, PageViews :8 })
    st_lru.Process(lru.LruData{Key:"key3", Timestamp:12345678, PageViews :8 })
    st_lru.Process(lru.LruData{Key:"key4", Timestamp:12345678, PageViews :8 })
    st_lru.Process(lru.LruData{Key:"key5", Timestamp:12345678, PageViews :8 })
    st_lru.Process(lru.LruData{Key:"key6", Timestamp:12345678, PageViews :8 })
    */

/*
    if element, ok := st_lru.Find("key1"); ok {
        if e, ok := element.Value.(lru.LruData) ; ok {
          println("timestamp is ", e.Timestamp)
          println("timestamp is ", e.Key)
          println("timestamp is ", e.PageViews)
        }else {
          println("not find this type!")
        }
    }
    if element, ok := st_lru.Find("key2"); ok {
        if e, ok := element.Value.(lru.LruData) ; ok {
          println("timestamp is ", e.Timestamp)
          println("timestamp is ", e.Key)
          println("timestamp is ", e.PageViews)
        }else {
          println("not find this type!")
        }
    }
    if element, ok := st_lru.Find("key3"); ok {
        if e, ok := element.Value.(lru.LruData) ; ok {
          println("timestamp is ", e.Timestamp)
          println("timestamp is ", e.Key)
          println("timestamp is ", e.PageViews)
        }else {
          println("not find this type!")
        }
    }
    if element, ok := st_lru.Find("key4"); ok {
        if e, ok := element.Value.(lru.LruData) ; ok {
          println("timestamp is ", e.Timestamp)
          println("timestamp is ", e.Key)
          println("timestamp is ", e.PageViews)
        }else {
          println("not find this type!")
        }
    }
    if element, ok := st_lru.Find("key5"); ok {
        if e, ok := element.Value.(lru.LruData) ; ok {
          println("timestamp is ", e.Timestamp)
          println("timestamp is ", e.Key)
          println("timestamp is ", e.PageViews)
        }else {
          println("not find this type!")
        }
    }
    */


    //lru.PushFront(LruData{"key2", 111222})
    /*
    if ok := st_lru.PushFront(lru.LruData{"key1", 1234567}) ; !ok {
        println("push element error, key1")
    }
    if ok := st_lru.PushFront(lru.LruData{"key2", 2234567}) ; !ok {
        println("push element error, key2")
    }
    if ok := st_lru.PushFront(lru.LruData{"key3", 3234567}) ; !ok {
        println("push element error, key3")
    }
    if ok := st_lru.PushFront(lru.LruData{"key4", 4234567}) ; !ok {
        println("push element error, key4")
    }
    if ok := st_lru.PushFront(lru.LruData{"key5", 5234567}) ; !ok {
        println("push element error, key5")
    }

    if element, ok := st_lru.Find("key5"); ok {
        if e, ok := element.Value.(lru.LruData) ; ok {
          println("timestamp is ", e.Timestamp)
        }else {
          println("not find this type!")
        }
    }

    vTest := new(ValueTest)
    vTest.name = "before is vTest"
    println("before vTest Name ",  vTest.name)
    vTest.SetName("now is vTest")
    println("after vTest Name ",  vTest.name)
    vTest.PointSetName("now is vTest")
    println("after vTest Name ",  vTest.name)
    */

    // doghttp.HttpCore()

}

func myRedisTest(){
    redisCmd := dogredis.RedisCmdFactory()
    redisCmd.SetString("key_hello", "value_hello", 20)
    /*
    ret_string := redisCmd.GetString("key_hello")
    println("main ret_string = ", ret_string)
    */
}

func myMysqlTest(id int){
  mysql_manager := mysql.MysqlFactory("root", "yangtao", "192.168.146.128:3306", "giftbox")
  mysql_manager.OpenOnceMysql()
  // mysql_manager.OpenMysql()
  println("pthread id is ", id)
  // mysql_manager.ConnDB()
  mysql_manager.Query()

  defer func () {
    mysql_manager.Close()
  }()

  //mysql_manager.OpenMysql()
}

/*
var (
  MaxWorker = os.Getenv("MAX_WORKERS")
  MaxQueue = os.Getenv("MAX_QUEUE")
)

type Dispatchar struct {
  WorkerPool chan chan Job
}

type CoreProcessor interface {
  UnpackRequest()
}

*/

func daemon_server() {
    service , err := daemon.New("name", "description")
    if err != nil {
      log.Fatal("Error:", err)
    }

    status , err := service.Install()
    if err != nil {
      log.Fatal(status, "\nError", err)
    }

    fmt.Println(status)
}

func redis_server_test() {
    // daemon_server()
    /* 作废*/
    //doghttp.HttpCore()
    fmt.Println("start http run()")
    doghttp.HttpRun()
    // doghttp.HttpCore()
}

 // var log = logging.MustGetLogger("example")
 var log = mylog.CreateLog("another")

// Example format string. Everything except the message has a custom color
// which is dependent on the log level. Many fields have a custom output
// formatting too, eg. the time returns the hour down to the milli second.
var format = logging.MustStringFormatter(
	`%{time:15:04:05.000} %{shortfunc} ▶ %{level:.4s} %{id:03x} %{message}`,
	// `%{color}%{time:15:04:05.000} %{shortfunc} ▶ %{level:.4s} %{id:03x}%{color:reset} %{message}`,
)

// Password is just an example type implementing the Redactor interface. Any
// time this is logged, the Redacted() function will be called.
type Password string

func (p Password) Redacted() interface{} {
	return logging.Redact(string(p))
}

func testLog() {
  // Open Log File
  logFile := "giftbox.log"
  logP, err := os.Create(logFile)
  defer logP.Close()
  if err != nil {
      fmt.Println(logFile, err)
      return
  }


	// For demo purposes, create two backend for os.Stderr.
	// backend1 := logging.NewLogBackend(os.Stderr, "", 0)
	backend1 := logging.NewLogBackend(logP, "", 0)
	// backend2 := logging.NewLogBackend(os.Stderr, "", 0)
	backend2 := logging.NewLogBackend(logP, "", 0)

	// For messages written to backend2 we want to add some additional
	// information to the output, including the used log level and the name of
	// the function.
	backend2Formatter := logging.NewBackendFormatter(backend2, format)

	// Only errors and more severe messages should be sent to backend1
	backend1Leveled := logging.AddModuleLevel(backend1)
	backend1Leveled.SetLevel(logging.ERROR, "")

	// Set the backends to be used.
	logging.SetBackend(backend1Leveled, backend2Formatter)

	log.Debugf("debug %s", Password("secret"))
	log.Info("info")
	log.Notice("notice")
	log.Warning("warning")
	log.Error("err")
	log.Critical("crit")
}

func testConfig() {
  cfg, err := ini.Load("etc/my.ini")
  fmt.Println("hello")
  if err != nil {
    return
  }
  fmt.Println("hello1")
  key, err := cfg.Section("mysql").GetKey("username")
  fmt.Println("hello2")
  if err != nil {
    return
  }
  fmt.Println("key value = ", key)
}

func register_service () {

    jobMap := dog.WorkMapFactory()

    //注册首页服务
    homepageJob := core.HomepageJob {}
    jobMap["homepage"] = homepageJob

    //注册redis缓存服务
    redisLruJob := core.RedisLruJob { RequestContent : "这是我测试的数据!"}
    jobMap["redis"] = &redisLruJob
}

func main () {

    //初始化系统配置信息
    config.LoadSystemConfig()

    //注册 job 服务
    register_service()

    //myLruTest()

    // 启动work服务
    redis_server_test()
    // myRedisTest()
    //test this is first run
    /*
    for i := 0 ; i < 10 ; i++ {
        go myMysqlTest( i )
    }
    go myMysqlTest( 10 )

    for i := 0 ; i < 1 ; {
      time.Sleep(1)
    }
    */

    //test http Server

    //测试全局workmap是否可用
    //test_work_service_map()

    //
    /* 日志函数像个垃圾，先不弄了
    mylog.LogFactory()
    log := mylog.GetLogger()
    log1 := mylog.CreateLog("another")
    log1.Error("haoshimaoskjdfksldfjk")
    mylog.DogError("This is DogError!")
    testLog()
    log.Error("This is my first err message!")
    */


    /*
    config2 := dog.ConfigFactory()()
    config2.Mysql.User = "giftbox"
    fmt.Println("config = ", config2 )

    config1 := dog.ConfigFactory()()
    fmt.Println("config = ", config1 )

    config.LoadConfig()
    */




/*
    config.TestConfig()
    fmt.Println("this value = ", config.TestNum)
    testLog()
    */

    //daemon for linux
    // fmt.Println("HelloS")
    // daemon_server()
    // time.Sleep(1)
    // fmt.Println("endS")
    //test this is second run
    // myMysqlTest()

}
